package com.apes.fn.scm.crossCompany.transfer.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.scm.crossCompany.transfer.model.CrossCompanyTransfer;
import com.apes.fn.scm.crossCompany.transfer.repository.CrossCompanyTransferRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.logger.ApesLoggerService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.outbox.OutboxPayloadWrapper;
import com.apes.framework.plugin.outbox.OutboxSubscriberService;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.framework.util.MapUtil;
import com.apes.pi.service.PiManager;
import com.apes.scm.account.account.model.InventoryBatch;
import com.apes.scm.account.transit.DepositInTransitService;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.pur.purchaseOrder.model.PurchaseOrderItem;
import com.apes.scm.pur.purchaseOrder.repository.PurchaseOrderItemRepository;
import com.apes.scm.rbac.repository.UserRepository;
import com.apes.scm.stock.transfer.model.Pick;
import com.apes.scm.stock.transfer.repository.PickRepository;
import com.apes.scm.voucher.model.VoucherItem;
import com.apes.scm.voucher.repository.VoucherItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @BelongsProject: apes-server
 * @BelongsPackage: com.apes.fn.scm.crossCompany.transfer.service
 * @ClassName: TransferHandleErpService
 * @Author: pyb
 * @CreateTime: 2020-07-03 14:46
 * @Description: 调拨至erp服务
 * @Version: 1.0
 */
@Service("transferHandleErpService")
public class TransferHandleErpService extends DomainService {
    CrossCompanyTransferRepository crossCompanyTransferRepository;

    @Autowired
    private void setCrossCompanyTransferRepository(CrossCompanyTransferRepository crossCompanyTransferRepository) {
        this.crossCompanyTransferRepository = crossCompanyTransferRepository;
    }

    /**
     * 处理 推送erp
     *
     * @param request
     * @return
     */
    private CrossCompanyTransfer handle(SimpleRequest request) {
        CrossCompanyTransfer companyTransfer = crossCompanyTransferRepository.findOne((String) request.get("id"));
        Optional.ofNullable(companyTransfer).orElseThrow(() -> new RuntimeException("无法找到跨公司调拨单"));
        JSONObject param = new JSONObject();
        Pick pick = SpringManager.getBean(PickRepository.class).findAll(JpaDsl.toCriteriaByEq("origin", companyTransfer.getId())).get(0);
        param.put("RKR", pick.getDoneUid() != null?pick.getDoneUid().getName():"");
        param.put("company", companyTransfer.getCompany().getId());
        param.put("shipLocation", companyTransfer.getShipLocation().getId());
        param.put("receiptLocation", companyTransfer.getReceiptLocation().getId());
        param.put("origin", companyTransfer.getId());
        param.put("transferType", companyTransfer.getTransferType().getId().equals("000159") ? 1 : 2);
        //传递一个唯一值用于幂等控制
        param.put("uniqueValue", UUID.randomUUID().toString());
        JSONArray items = new JSONArray();
        companyTransfer.getCrossCompanyTransferItems().forEach(crossCompanyTransferItem -> {
            //找商品库存价值
            InventoryBatch inventoryBatch = crossCompanyTransferItem.getInventoryBatch();
            //通过商品库存价值 找采购凭证
            VoucherItem vItem = SpringManager.getBean(VoucherItemRepository.class).findOne(inventoryBatch.getBatchNumber());
            //找到源单据(采购订单明细)
            PurchaseOrderItem orderItem = SpringManager.getBean(PurchaseOrderItemRepository.class).findOne(Long.valueOf(vItem.getOriginItemId()));

            Optional.ofNullable(orderItem).orElseThrow(() -> new RuntimeException("通过商品库存价值未找到源单据(采购订单明细)"));

            JSONObject item = new JSONObject();
            item.put("product", crossCompanyTransferItem.getProduct().getOrginID());
            item.put("itemId", crossCompanyTransferItem.getId());
            item.put("classify", crossCompanyTransferItem.getProduct().getClassify().getId());
            item.put("brandId", crossCompanyTransferItem.getProduct().getBrand().getId());
            item.put("priceUnit", crossCompanyTransferItem.getPriceUnit());
            item.put("productReturnQty", crossCompanyTransferItem.getProductReturnQty());
            item.put("supplier", orderItem.getName());
            item.put("origin", crossCompanyTransferItem.getId());
            item.put("cooperation", orderItem.getPurchaseOrder().getCooperation().getId());
            items.add(item);
        });
        //区分经代销
        items.stream().collect(Collectors.groupingBy(x -> {
            JSONObject item = (JSONObject) x;
            return item.getString("cooperation").equals("distribution");
        })).forEach((k, v) -> {
            if (k) {
                param.put("HZFS", 0);
                param.put("items", v);

            } else {
                param.put("HZFS", 1);
                param.put("items", v);
            }
//            SpringManager.getBean(PiManager.class).synErp("ipmEsbInventoryService.exec_crossCompanyTransfer_deal", param);
            SpringManager.getBean(OutboxSubscriberService.class).commonSendRequest("local:transferHandleErpService.handleCross", "kgsHandle:" + companyTransfer.getId(), param);
        });

        return companyTransfer;
    }

    @OutboxSubscriber(id="local:transferHandleErpService.handleCross", name = "跨公司流转erp单据")
    private void handleCross(OutboxPayloadWrapper outboxPayloadWrapper) {
        SpringManager.getBean(PiManager.class).synErp("ipmEsbInventoryService.exec_crossCompanyTransfer_deal", outboxPayloadWrapper.getPayload());
    }

    /**
     * 处理erp收货动作
     *
     * @param request
     * @return
     */
    private void receipt(SimpleRequest request) {
        JSONObject requestJO = request.getJO();
        if (!"CrossCompanyTransfer".equals(requestJO.getString("sourceType"))) {
            throw new RuntimeException(String.format("推送收货事件异常！单据[%s][%s]不是赋能跨公司调拨单据", requestJO.getString("source"), requestJO.getString("sourceType")));
        }
        //都是一次性收货 不考虑拒收  判断总数
        double receiptSum = requestJO.getJSONArray("orderItems").stream().mapToDouble((items) -> Math.abs(((JSONObject) items).getDouble("productUomQty"))).sum();
        CrossCompanyTransfer source = crossCompanyTransferRepository.findOne(requestJO.getString("source"));
        Optional.ofNullable(source).orElseThrow(() -> new RuntimeException(String.format("未找到跨公司调拨单[%s]！单据已被删除或失效，请检查！", requestJO.getString("source"))));
        if (source.getState().equals("ship")) {
            source.delivery(receiptSum);
            source.setCrossSystem("erp");
            if (source.getQtyTotal() == source.getQtyReceived()) {
                source.setState("receipt");
            }
            if (source.getState().equals("receipt")){
                Object object = MapUtil.mapper("businessType", source.getInnerBusinessType(),
                        "businessKey", source.getId(),
                        "operator_id",
                        SpringManager.getBean(UserRepository.class).findAll(
                                JpaDsl.toCriteriaByEq("person.id", requestJO.getJSONObject("approveUid").get("id"))).stream().findFirst().get().getId(), 
								"operate", "跨公司调拨:收货",
                        "workPostName",request.getSession() != null ? request.getSession().getAttribute("workPostName", String.class) : null);
                SpringManager.getBean(ApesLoggerService.class).sendSynEvent("event:ir.logger.create", object);

                CrossCompanyTransfer transfer = crossCompanyTransferRepository.saveAndFlush(source);

                /**删除未达帐**/
                DepositInTransitService depositInTransitService = SpringManager.getBean(DepositInTransitService.class);
                transfer.getCrossCompanyTransferItems().stream().forEach(item -> {
                    depositInTransitService.delete(transfer.getInnerBusinessType(), transfer.getInnerBusinessKey(),
                            item.getId(), transfer.getReceiptLocation());
                });
            }
        }
    }
}
